package com.ztgf.order.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.ztgf.commodity.models.dto.BrandInfoDTO;
import com.ztgf.commodity.models.dto.CommodityInfoDTO;
import com.ztgf.commodity.models.service.IBrandInfoService;
import com.ztgf.commodity.models.service.ICommodityInfoService;
import com.ztgf.commodity.models.vo.CommodityEsVO;
import com.ztgf.common.bo.HeadParamsBO;
import com.ztgf.common.constant.CommonParameter;
import com.ztgf.common.constant.Result;
import com.ztgf.common.enums.CodeEnum;
import com.ztgf.common.utils.CustomizeUtil;
import com.ztgf.common.utils.DateUtils;
import com.ztgf.common.utils.StrUtils;
import com.ztgf.db.utils.RedisUtil;
import com.ztgf.dubbo.exception.ServiceException;
import com.ztgf.message.model.bo.MessageAnnouncementSaveBO;
import com.ztgf.message.model.constant.MessageTopicType;
import com.ztgf.message.model.dto.ResponseDTO;
import com.ztgf.message.model.enums.MessageEnum;
import com.ztgf.message.model.service.IKafkaProducerService;
import com.ztgf.order.common.config.YmlConfig;
import com.ztgf.order.constant.OrderConstant;
import com.ztgf.order.mapper.OrderInfoMapper;
import com.ztgf.order.mapper.OrderPaymentTypeMapper;
import com.ztgf.order.models.bo.*;
import com.ztgf.order.models.bo.pay.PayOrderSaveBO;
import com.ztgf.order.models.constant.OrderExpireTimeConstant;
import com.ztgf.order.models.dto.*;
import com.ztgf.order.models.dto.purchase.PurchaseCommodityBargainDTO;
import com.ztgf.order.models.dto.purchase.PurchaseCommodityDTO;
import com.ztgf.order.models.dto.purchase.PurchaseInfoDTO;
import com.ztgf.order.models.enums.BargainStateEnum;
import com.ztgf.order.models.enums.OrderStateEnum;
import com.ztgf.order.models.service.*;
import com.ztgf.order.models.service.pay.IPayService;
import com.ztgf.order.models.service.purchase.IPurchaseCommodityBargainService;
import com.ztgf.order.models.service.purchase.IPurchaseCommodityService;
import com.ztgf.order.models.service.purchase.IPurchaseInfoService;
import com.ztgf.order.models.vo.*;
import com.ztgf.pay.models.bo.PayOrderMotherSaveBO;
import com.ztgf.pay.models.dto.PayOrderMotherDTO;
import com.ztgf.pay.models.service.IPayOrderRepayService;
import com.ztgf.pay.models.service.IPayOrderService;
import com.ztgf.search.models.dto.EsGoodsDTO;
import com.ztgf.search.models.service.ElasticsearchService;
import com.ztgf.shopping.models.bo.shop.ShopQiyuesuoAuthStateInfoBO;
import com.ztgf.shopping.models.dto.shop.ShopAddressDTO;
import com.ztgf.shopping.models.dto.shop.ShopContractParamRelationDTO;
import com.ztgf.shopping.models.dto.shop.ShopInfoDTO;
import com.ztgf.shopping.models.dto.template.ContractTempletDTO;
import com.ztgf.shopping.models.service.shop.*;
import com.ztgf.shopping.models.service.template.IContractTempletService;
import com.ztgf.shopping.models.vo.shop.ShopInfoVO;
import com.ztgf.sms.models.bo.SmsInfoSaveBO;
import com.ztgf.sms.models.service.ISmsInfoService;
import com.ztgf.sys.models.dto.SysAreaDTO;
import com.ztgf.sys.models.dto.SysDictDTO;
import com.ztgf.sys.models.dto.SysUserDTO;
import com.ztgf.sys.models.service.ISysAreaService;
import com.ztgf.sys.models.service.ISysDictService;
import com.ztgf.user.models.dto.UserInfoDTO;
import com.ztgf.user.models.service.IUserLoginService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.yaml.snakeyaml.events.Event;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

import static com.ztgf.common.utils.UtilConstants.isNull;

/**
 * 订单表控制器
 *
 * @author zeming.lv
 * @Date 2021-09-16 15:32:26
 */
@Slf4j
@DubboService
@Lazy
public class OrderPaymentTypeServiceImpl extends ServiceImpl<OrderPaymentTypeMapper, OrderPaymentTypeDTO> implements IOrderPaymentTypeService {

    @Resource
    private YmlConfig ymlConfig;

    @Autowired
    private IOrderPaymentScaleService orderPaymentScaleService;

    @Autowired
    private IOrderInfoService orderInfoService;

    @Autowired
    private IOrderStatusService orderStatusService;

    @Autowired
    private RedisUtil redisUtil;

    @DubboReference
    private IShopContractParamRelationService shopContractParamRelationService;
    @Autowired
    private IOrderPayRelationService orderPayRelationService;

    @Override
    @Transactional(rollbackFor= Exception.class)
    public  Result saveOrUpdateOrderPaymentType(OrderPaymentTypeBO orderPaymentTypeBO){
        HeadParamsBO headParamsBO = CommonParameter.getHeadParamsBO();
        UserInfoDTO userInfoDTO = (UserInfoDTO) redisUtil.getSession(headParamsBO.getSessionId(), headParamsBO.getSource() + "");//获取操作人

        OrderInfoDTO orderInfoDTO = orderInfoService.selectById(orderPaymentTypeBO.getOrderId());
        if(null == orderInfoDTO){
            return new Result(CodeEnum.FAIL_100002);
        }
        OrderStatusDTO orderStatusDTO = orderStatusService.getByOrderId(orderPaymentTypeBO.getOrderId());
        if(orderStatusDTO == null || orderStatusDTO.getOrderState() != 0){
            return new Result(CodeEnum.FAIL_100075);
        }
        //根据订单删除对应支付方式
        Wrapper<OrderPaymentTypeDTO> orderPaymentTypeDTOWrapper = new EntityWrapper<>();
        orderPaymentTypeDTOWrapper.eq("order_id",orderInfoDTO.getId());
        baseMapper.delete(orderPaymentTypeDTOWrapper);

        //根据订单删除对应支付比例
        Wrapper<OrderPaymentScaleDTO> orderPaymentScaleDTOWrapper = new EntityWrapper<>();
        orderPaymentScaleDTOWrapper.eq("order_id",orderInfoDTO.getId());
        orderPaymentScaleService.delete(orderPaymentScaleDTOWrapper);

        OrderPaymentTypeDTO dto = new OrderPaymentTypeDTO();
        BeanUtils.copyProperties(orderPaymentTypeBO, dto);
        List<Integer> paymentTypeList = orderPaymentTypeBO.getPaymentType();
        for(Integer paymentType : paymentTypeList){
            Long id = ymlConfig.getPkId();
            dto.setId(id);
            dto.setPaymentType(paymentType);
           //dto.setCreateUserId(userInfoDTO.getCreateUserId());
            //dto.setUpdateUserId(userInfoDTO.getUpdateUserId());
            dto.setBuyShopId(orderInfoDTO.getBuyShopId());
            dto.setSellShopId(orderInfoDTO.getSellShopId());
            if(paymentTypeList.contains(OrderConstant.ORDER_PAYMENT_TYPE_CREDIT)){
                if(paymentType == OrderConstant.ORDER_PAYMENT_TYPE_CREDIT && CustomizeUtil.listIsNotNull(orderPaymentTypeBO.getOrderPaymentScaleBOList())){
                    try{
                        orderPaymentScaleService.addPaymentScaleByList(orderPaymentTypeBO.getOrderPaymentScaleBOList(),id,orderInfoDTO);
                        this.insert(dto);
                        //增加默认的店铺赊销合同模板
                        shopContractParamRelationService.createDefaultShopContractInfoByCredit(orderInfoDTO.getSellShopId());
                    }catch (Exception e){
                        log.error(e.getMessage());
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        return new Result(CodeEnum.FAIL_100076);
                    }
                }else if(paymentType == OrderConstant.ORDER_PAYMENT_TYPE_BILL){
                    //票据不需要买家确认，默认买家也确认
                    dto.setType(1);
                    this.insert(dto);
                }else{
                    this.insert(dto);
                }
            }else{
                //不包含赊销的情况，票据和现金都默认为1
                dto.setType(1);
                this.insert(dto);
            }
        }

        return new Result(CodeEnum.SUCCESS);
    }



    @Override
    public List<OrderPaymentTypeVO> getOrderPaymentType(Long id) {
        OrderInfoDTO orderInfoDTO = orderInfoService.selectById(id);
        List<OrderPaymentTypeVO> paymentTypeList  = new ArrayList<>();
        OrderPaymentTypeVO orderPaymentTypeCASHVO = new OrderPaymentTypeVO();
        OrderPaymentTypeVO orderPaymentTypeBILLVO = new OrderPaymentTypeVO();
        OrderPaymentTypeVO orderPaymentTypeCREDITVO = new OrderPaymentTypeVO();
        //判断是否为预售(全款则不为预售)
        if(orderInfoDTO.getPayType() == OrderConstant.ORDER_PAY_TYPE_PAID){
            //判断是否有砍价服务费
            if(orderInfoDTO.getPurchaseFeeMoneyScalePrice().compareTo(BigDecimal.ZERO) == 0){
                //设置支付类型(0现鑫/网银/余额、1赊销、2票据)
                orderPaymentTypeCASHVO.setPaymentType(OrderConstant.ORDER_PAYMENT_TYPE_CASH);
                orderPaymentTypeCREDITVO.setPaymentType(OrderConstant.ORDER_PAYMENT_TYPE_CREDIT);
                orderPaymentTypeBILLVO.setPaymentType(OrderConstant.ORDER_PAYMENT_TYPE_BILL);
                paymentTypeList = Arrays.asList(orderPaymentTypeCASHVO,orderPaymentTypeCREDITVO,orderPaymentTypeBILLVO);
            }else{
                //设置支付类型(0现鑫/网银/余额、1赊销、2票据)
                orderPaymentTypeCREDITVO.setPaymentType(OrderConstant.ORDER_PAYMENT_TYPE_CREDIT);
                orderPaymentTypeCASHVO.setPaymentType(OrderConstant.ORDER_PAYMENT_TYPE_CASH);
                paymentTypeList = Arrays.asList(orderPaymentTypeCASHVO,orderPaymentTypeCREDITVO);
            }

        }else{
            //判断是否有砍价服务费
            if (orderInfoDTO.getPurchaseFeeMoneyScalePrice().compareTo(BigDecimal.ZERO) == 0) {
                //设置支付类型(0现鑫/网银/余额、1赊销、2票据)
                orderPaymentTypeCASHVO.setPaymentType(OrderConstant.ORDER_PAYMENT_TYPE_CASH);
                orderPaymentTypeBILLVO.setPaymentType(OrderConstant.ORDER_PAYMENT_TYPE_BILL);
                paymentTypeList = Arrays.asList(orderPaymentTypeCASHVO,orderPaymentTypeBILLVO);
            }else{
                //设置支付类型(0现鑫/网银/余额、1赊销、2票据)
                orderPaymentTypeCASHVO.setPaymentType(OrderConstant.ORDER_PAYMENT_TYPE_CASH);
                paymentTypeList = Arrays.asList(orderPaymentTypeCASHVO);
            }

        }
        return paymentTypeList;
    }

    @Override
    public OrderPaymentTypeDTO getOrderPaymentByOrderIdAndType(Long orderId, Integer type,Integer paymentType) {
        //根据订单id和类型查询
        Wrapper<OrderPaymentTypeDTO> orderPaymentTypeDTOWrapper = new EntityWrapper<>();
        orderPaymentTypeDTOWrapper.eq("order_id",orderId);
        orderPaymentTypeDTOWrapper.eq("type",type);
        orderPaymentTypeDTOWrapper.eq("payment_type",paymentType);
        List<OrderPaymentTypeDTO> orderPaymentTypeDTOList = baseMapper.selectList(orderPaymentTypeDTOWrapper);
        if(CustomizeUtil.listIsNotNull(orderPaymentTypeDTOList)){
            return orderPaymentTypeDTOList.get(0);
        }
        return null;
    }


    @Override
    public OrderPaymentTypeDTO getOrderPaymentByOrderIdAndPaymentType(Long orderId,Integer paymentType) {
        //根据订单id和类型查询
        Wrapper<OrderPaymentTypeDTO> orderPaymentTypeDTOWrapper = new EntityWrapper<>();
        orderPaymentTypeDTOWrapper.eq("order_id",orderId);
        orderPaymentTypeDTOWrapper.eq("payment_type",paymentType);
        List<OrderPaymentTypeDTO> orderPaymentTypeDTOList = baseMapper.selectList(orderPaymentTypeDTOWrapper);
        if(CustomizeUtil.listIsNotNull(orderPaymentTypeDTOList)){
            return orderPaymentTypeDTOList.get(0);
        }
        return null;
    }



    @Override
    public boolean saveDefaultOrderPaymentType(OrderInfoVO orderInfoVO) {
        HeadParamsBO headParamsBO = CommonParameter.getHeadParamsBO();
//        UserInfoDTO userInfoDTO = (UserInfoDTO) redisUtil.getSession(headParamsBO.getSessionId(), headParamsBO.getSource() + "");//获取操作人

        //根据订单删除对应支付方式
        Wrapper<OrderPaymentTypeDTO> orderPaymentTypeDTOWrapper = new EntityWrapper<>();
        orderPaymentTypeDTOWrapper.eq("order_id",orderInfoVO.getId());
        baseMapper.delete(orderPaymentTypeDTOWrapper);

        OrderPaymentTypeDTO dto = new OrderPaymentTypeDTO();
        Long id = ymlConfig.getPkId();
        dto.setId(id);
        dto.setPaymentType(OrderConstant.ORDER_PAYMENT_TYPE_CASH);
//        dto.setCreateUserId(userInfoDTO.getCreateUserId());
//        dto.setUpdateUserId(userInfoDTO.getUpdateUserId());
        dto.setBuyShopId(orderInfoVO.getBuyShopId());
        dto.setSellShopId(orderInfoVO.getSellShopId());
        dto.setOrderId(orderInfoVO.getId());
        dto.setType(1);
        return this.insert(dto);
    }

    @Override
    public Result updateOrderPaymentType(List<OrderPaymentTypeVO> orderPaymentTypeVOList) {
        for(OrderPaymentTypeVO orderPaymentTypeVO : orderPaymentTypeVOList){

            OrderStatusDTO orderStatusDTO = orderStatusService.getByOrderId(orderPaymentTypeVO.getOrderId());
            if(orderStatusDTO == null || orderStatusDTO.getOrderState() != 0){
                return new Result(CodeEnum.FAIL_100075);
            }

            OrderPaymentTypeDTO orderPaymentTypeDTO = baseMapper.selectById(orderPaymentTypeVO.getId());
            if(null == orderPaymentTypeDTO){
                return new Result(CodeEnum.FAIL_100074);
            }
            orderPaymentTypeDTO.setType(orderPaymentTypeVO.getType());
            baseMapper.updateById(orderPaymentTypeDTO);
        }
        return new Result(CodeEnum.SUCCESS);
    }

    @Override
    public List<OrderPaymentTypeDTO> queryList(Long orderId) {
        Wrapper wrapper = new EntityWrapper<>();
        wrapper.eq("order_id", orderId);
        return this.selectList(wrapper);
    }

    @Override
    public void updatePayStatus(Long orderId, Long payRelationId) {

        boolean allPaySuccess = orderPayRelationService.getOrderAllPaySuccess(orderId, payRelationId);
        if(allPaySuccess){
            //修改订单状态
            //赊销订单
            OrderPaymentTypeDTO typeDTO = this.getOrderPaymentByOrderIdAndType(orderId, 1,2);

            if(typeDTO == null){
                OrderStatusDTO statusDTO = orderStatusService.getByOrderId(orderId);
                if(statusDTO.getContactState() == 2){
                    OrderStatusDTO newStatusDTO = new OrderStatusDTO();
                    newStatusDTO.setOrderState(3);
                    Wrapper wrapper = new EntityWrapper();
                    wrapper.eq("order_id", orderId);
                    wrapper.in("order_state", "1,2");
                    if(!orderStatusService.update(newStatusDTO, wrapper)){
                        throw new ServiceException(CodeEnum.FAIL_100003);
                    }
                }
            } else {
                OrderPaymentTypeDTO newTypeDTO = new OrderPaymentTypeDTO();
                newTypeDTO.setPaymentStatus(1);
                Wrapper wrapperType = new EntityWrapper();
                OrderStatusDTO statusDTO = orderStatusService.getByOrderId(orderId);
                OrderStatusDTO newStatusDTO = new OrderStatusDTO();
                if(typeDTO.getReceiveStatus() == 1){
                    newStatusDTO.setOrderState(5);
                    newTypeDTO.setReceiveStatus(2);
                    wrapperType.eq("receive_status", typeDTO.getReceiveStatus());
                    Wrapper wrapper = new EntityWrapper();
                    wrapper.eq("order_id", orderId);
                    wrapper.eq("order_state", statusDTO.getOrderState());
                    if(!orderStatusService.update(newStatusDTO, wrapper)){
                        throw new ServiceException(CodeEnum.FAIL_100003);
                    }
                }
                wrapperType.eq("id", typeDTO.getId());
                if(!this.update(newTypeDTO, wrapperType)){
                    throw new ServiceException(CodeEnum.FAIL_100003);
                }
            }
        }
    }


}
